/**
 * This file is part of Idegen, the application to create IDE project files.
 *
 * @copyright Copyright (c) 2011-2012, Walter Tamboer http://waltertamboer.nl
 * @file Idegen/Idegen/IdegenProjectConfig.cpp
 */

#include "Idegen/PrecompiledHeader.hpp"
#include "Idegen/Idegen/IdegenProjectConfig.hpp"
#include "Idegen/Idegen/IdegenPrecompiledHeader.hpp"
#include "Idegen/Idegen/Charset.hpp"
#include "Idegen/Application/Settings.hpp"

namespace Idegen
{
	IdegenProjectConfig::IdegenProjectConfig()
		: m_Charset( CharsetUnknown ), m_PrecompiledHeader( NULL ), m_UseDebugLibraries( false ), 
		m_WarningLevel( 0 ), m_WarningsAsErrors( false )
	{
	}

	IdegenProjectConfig::~IdegenProjectConfig()
	{
		delete m_PrecompiledHeader;
	}

	Charset IdegenProjectConfig::GetCharset() const
	{
		return m_Charset;
	}
	
	DefinitionList IdegenProjectConfig::GetDefinitions() const
	{
		return m_Definitions;
	}

	IncludePathList IdegenProjectConfig::GetIncludeDirectories() const
	{
		return m_IncludeDirectories;
	}

	LibraryPathList IdegenProjectConfig::GetLibraryDirectories() const
	{
		return m_LibraryDirectories;
	}

	std::string IdegenProjectConfig::GetName() const
	{
		return m_Name;
	}

	std::string IdegenProjectConfig::GetOutputPath() const
	{
		return m_OutputPath;
	}

	std::string IdegenProjectConfig::GetPlatform() const
	{
		return m_Platform;
	}

	std::string IdegenProjectConfig::GetTempPath() const
	{
		return m_TempPath;
	}

	IdegenPrecompiledHeader* IdegenProjectConfig::GetPrecompiledHeader() const
	{
		return m_PrecompiledHeader;
	}

	int IdegenProjectConfig::GetWarningLevel() const
	{
		return m_WarningLevel;
	}

	void IdegenProjectConfig::ParseAttributes( Settings* settings, TiXmlElement* parent )
	{
		ParseAttributeString( parent, "name", m_Name );
		m_Name = settings->ParseVariables( m_Name );

		ParseAttributeString( parent, "platform", m_Platform );
		m_Platform = settings->ParseVariables( m_Platform );
	}

	void IdegenProjectConfig::ParsePrecompiledHeader( Settings* settings, TiXmlElement* parent )
	{
		m_PrecompiledHeader = new IdegenPrecompiledHeader();

		TiXmlElement* element = parent->FirstChildElement();
		while ( element != NULL )
		{
			const std::string elementName = element->Value();
			
			if ( elementName == "i:name" )
			{
				ParseElementString( element, m_PrecompiledHeader->Name );
				m_PrecompiledHeader->Name = settings->ParseVariables( m_PrecompiledHeader->Name );
			}
			else if ( elementName == "i:file" )
			{
				ParseElementString( element, m_PrecompiledHeader->File );
				m_PrecompiledHeader->File = settings->ParseVariables( m_PrecompiledHeader->File );
			}

			element = element->NextSiblingElement();
		}

		if ( m_PrecompiledHeader->Name == "" || m_PrecompiledHeader->File == "" )
		{
			delete m_PrecompiledHeader;
			m_PrecompiledHeader = NULL;
		}
	}

	void IdegenProjectConfig::Unserialize( Settings* settings, TiXmlElement* parent )
	{
		ParseAttributes( settings, parent );

		TiXmlElement* element = parent->FirstChildElement();
		while ( element != NULL )
		{
			const std::string elementName = element->Value();
			
			if ( elementName == "i:output" )
			{
				ParseAttributeString( element, "path", m_OutputPath );
				m_OutputPath = settings->ParseVariables( m_OutputPath );
			}
			else if ( elementName == "i:temp" )
			{
				ParseAttributeString( element, "path", m_TempPath );
				m_TempPath = settings->ParseVariables( m_TempPath );
			}
			else if ( elementName == "i:charset" )
			{
				std::string charset;
				if ( ParseAttributeString( element, "type", charset ) )
				{
					std::transform( charset.begin(), charset.end(), charset.begin(), ::tolower );
					if ( charset == "unicode" )
					{
						m_Charset = CharsetUnicode;
					}
					else if ( charset == "" )
					{
						m_Charset = CharsetMultiByte;
					}
					else
					{
						m_Charset = CharsetUnknown;
					}
				}
			}
			else if ( elementName == "i:debug-libraries" )
			{
				m_UseDebugLibraries = false;
				ParseElementBoolean( element, m_UseDebugLibraries );
			}
			else if ( elementName == "i:definition" )
			{
				std::string value;
				if ( ParseElementString( element, value ) )
				{
					value = settings->ParseVariables( value );
					m_Definitions.push_back( value );
				}
			}
			else if ( elementName == "i:include-directory" )
			{
				std::string value;
				if ( ParseAttributeString( element, "path", value ) )
				{
					value = settings->ParseVariables( value );
					m_IncludeDirectories.push_back( value );
				}
			}
			else if ( elementName == "i:library-directory" )
			{
				std::string value;
				if ( ParseAttributeString( element, "path", value ) )
				{
					value = settings->ParseVariables( value );
					m_LibraryDirectories.push_back( value );
				}
			}
			else if ( elementName == "i:precompiled-header" )
			{
				ParsePrecompiledHeader( settings, element );
			}
			else if ( elementName == "i:warnings-as-errors" )
			{
				m_WarningsAsErrors = false;
				ParseElementBoolean( element, m_WarningsAsErrors );
			}
			else if ( elementName == "i:warning-level" )
			{
				ParseElementInt( element, m_WarningLevel );
			}

			element = element->NextSiblingElement();
		}
	}

	bool IdegenProjectConfig::UseDebugLibraries() const
	{
		return m_UseDebugLibraries;
	}

	bool IdegenProjectConfig::UseWarningsAsErrors() const
	{
		return m_WarningsAsErrors;
	}
}
